package tracer

import (
	"context"
	"log"

	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/exporters/jaeger"
	"go.opentelemetry.io/otel/sdk/resource"
	"go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
)

const (
	serviceNameKey = "ginweb"
)

type Tracer struct {
	TracerProvider *trace.TracerProvider
	batcher        trace.SpanProcessor
}

func NewTracer(serviceName, endpoint string) (*Tracer, error) {
	exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(endpoint)))
	if err != nil {
		log.Printf("failed to create jaeger exporter: %v", err)
		return nil, err
	}

	batcher := trace.NewBatchSpanProcessor(exp)
	tp := trace.NewTracerProvider(
		trace.WithSpanProcessor(batcher),
		trace.WithResource(resource.NewWithAttributes(
			semconv.SchemaURL,
			semconv.ServiceNameKey.String(serviceName),
		)),
	)

	otel.SetTracerProvider(tp)

	return &Tracer{
		TracerProvider: tp,
		batcher:        batcher,
	}, nil
}

func (t *Tracer) Shutdown() error {
	if err := t.batcher.Shutdown(context.Background()); err != nil {
		log.Printf("failed to shutdown batcher: %v", err)
		return err
	}
	if err := t.TracerProvider.Shutdown(context.Background()); err != nil {
		log.Printf("failed to shutdown tracer provider: %v", err)
		return err
	}
	return nil
}
